package matrici;

import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.*;
import javax.swing.*;

/**
 * 
 * @author Luca
 */
public class LUPDecomp extends JPanel implements ActionListener, KeyListener {

    static JFrame f;
    JPanel intro, fin, pA, pI, pGo;
    JTextField dimMatrice;
    JTextField[] vettorePermutazioni;
    JTextField[][] mA, mI;
    JButton go, jordan;
    int dim = 0;
    private JPanel pPer;

    /**
     * 
     */
    public LUPDecomp() {
        intro = new JPanel();
        this.add(intro);
        intro.add(new JLabel("Dimensione matrice"));
        dimMatrice = new JTextField();
        dimMatrice.setPreferredSize(new Dimension(40, 20));
        intro.add(dimMatrice);
        dimMatrice.addKeyListener(this);
    }

    /**
     * 
     * @param args
     */
    public static void main(String[] args) {
        LUPDecomp m = new LUPDecomp();
        f = new JFrame();
        f.setVisible(true);
        f.setTitle("Matrice inversa");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocation(200, 200);
        f.add(m);

        f.pack();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(go)) {
            double[][] matrice = new double[dim][dim];
            for (int i = 0; i < dim; i++) {
                for (int j = 0; j < dim; j++) {
                    matrice[i][j] = new Double(mA[i][j].getText());
                }
            }
            int[] permutazioni = new int[dim];
            for (int i = 0; i < dim; i++) {
                permutazioni[i] = i;
            }
            LUPOperation(matrice, permutazioni);
            for (int i = 0; i < dim; i++) {
                for (int j = 0; j < dim; j++) {
                    DecimalFormat df = new DecimalFormat("0.##");
                    mA[i][j].setText(df.format(matrice[i][j]));
                }
            }
            for (int i = 0; i < dim; i++) {
                vettorePermutazioni[i].setText(new Integer(permutazioni[i]).toString());
            }
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
        if (e.getSource().equals(dimMatrice)) {
            char typed = e.getKeyChar();
            if (typed != '0' && typed != '1' && typed != '2' && typed != '3'
                    && typed != '4' && typed != '5' && typed != '6' && typed != '7'
                    && typed != '8' && typed != '9' && typed != '\n' && typed != '\b') {
                String temp = dimMatrice.getText();
                temp = temp.substring(0, temp.length() - 1);
                dimMatrice.setText(temp);
            }
            if (e.getKeyChar() == '\n') {
                try {
                    dim = new Integer(dimMatrice.getText());
                } catch (NumberFormatException ne) {
                    dim = 0;
                }
                if (dim > 0) {
                    inserisci();
                }
            }
        }
    }

    void inserisci() {
        intro.setVisible(false);

        fin = new JPanel();
        pA = new JPanel();
        pGo = new JPanel();
        pPer = new JPanel();

        pA.setLayout(new GridLayout(dim, dim));
        mA = new JTextField[dim][dim];
        Random generator = new Random();
        for (int i = 0; i < dim; i++) {
            for (int j = 0; j < dim; j++) {
                mA[i][j] = new JTextField();
                mA[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK));
                mA[i][j].setPreferredSize(new Dimension(40, 20));
                //mA[i][j].setText(new Integer(generator.nextInt(4)).toString());
                pA.add(mA[i][j]);
            }
        }

        go = new JButton("Go");
        go.addActionListener(this);

        pGo.add(go);

        pPer.setLayout(new GridLayout(dim, 1));
        vettorePermutazioni = new JTextField[dim];
        for (int i = 0; i < dim; i++) {
            vettorePermutazioni[i] = new JTextField();
            vettorePermutazioni[i].setBorder(BorderFactory.createLineBorder(Color.BLACK));
            vettorePermutazioni[i].setPreferredSize(new Dimension(20, 20));
            vettorePermutazioni[i].setText(new Integer(i).toString());
            pPer.add(vettorePermutazioni[i]);
        }

        fin.add(pA);
        fin.add(pPer);
        fin.add(pGo);


        this.add(fin);
        f.pack();
    }

    private void LUPOperation(double matrice[][], int[] permutazioni) {
        for (int i = 0; i < dim; i++) {
            double max = Double.MIN_VALUE;
            int jMax = i;
            for (int j = i; j < dim; j++) {
                if (matrice[j][i] >= max | -matrice[j][i] >= max) {
                    max = matrice[j][i];
                    jMax = j;
                }
            }
            if (jMax!=i) {
                double temp[];
                temp = matrice[i];
                matrice[i] = matrice[jMax];
                matrice[jMax] = temp;
                
                int t;
                t = permutazioni[i];
                permutazioni[i] = permutazioni[jMax];
                permutazioni[jMax] = t;
            }

            for (int j = i + 1; j < dim; j++) {
                matrice[j][i] /= matrice[i][i];
            }
            for (int j = i + 1; j < dim; j++) {
                for (int k = i + 1; k < dim; k++) {
                    matrice[j][k] -= matrice[i][k] * matrice[j][i];
                }
            }
        }
    }
}